package com.xtaller.lazy.api.base;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xtaller.lazy.base.TApi;
import com.xtaller.lazy.lib.R;
import com.xtaller.lazy.lib.annotation.Permission;
import com.xtaller.lazy.lib.convert.J;
import com.xtaller.lazy.lib.convert.L;
import com.xtaller.lazy.lib.convert.M;
import com.xtaller.lazy.lib.convert.V;
import com.xtaller.lazy.model.base.Department;
import com.xtaller.lazy.model.base.User;
import com.xtaller.lazy.model.base.UserDepartment;
import com.xtaller.lazy.model.system.Dict;
import com.xtaller.lazy.parameter.DocDepartment;
import com.xtaller.lazy.parameter.DocUserDept;
import com.xtaller.lazy.service.base.DepartmentService;
import com.xtaller.lazy.service.base.UserDepartmentService;
import com.xtaller.lazy.service.base.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @version V1.0
 * @author: Taller
 * @date: 2019-04-16
 * @Description: 部门管理api
 */
@Api(tags = "部门管理api")
@RestController
@RequestMapping("/v1/base")
public class DepartmentApi extends TApi {
    @Autowired private DepartmentService deptService;
    @Autowired private UserDepartmentService userDeptService;
    @Autowired private UserService userService;

    private Map<String, String> baseVerify() {
        var verify = M.create("fullName", "部门全称不能为空");
        return verify;
    }
    private Map<String, String> deptUserVerify() {
        var verify = M.create("departmentId", "部门id不能为空")
                        .put("userId", "用户id不能为空");
        return verify;
    }

    @GetMapping("/dept")
    @ApiOperation("读取数据")
    @Permission(authorities = "base-dept-tree")
    public Object table(){
        var qw = new QueryWrapper<Department>();
        qw.lambda().orderByDesc(Department::getOrderNumber);
        var depts = deptService.list(qw);
        // 创建一个默认部门
        if(depts.size() == 0){
            var dept = new Department();
            dept.setFullName("总经办");
            dept.setShortName("总经办");
            dept.setOrderNumber(999);
            dept.setParentId(0L);
            deptService.save(dept);
            depts = deptService.list(qw);
        }
        var list = formatDept(depts);
        var data = J.create("list", list).put("tree", L.list2Tree(list, 0L));
        return R.ok(data);
    }


    @PostMapping("/dept")
    @ApiOperation("创建")
    @Permission(authorities = "base-dept-create")
    public Object create(@ApiParam("数据对象") @RequestBody DocDepartment object){
        var check = V.checkEmpty(baseVerify(), object);
        if (check.getBoolean(CHECK)) {
            return R.error(check.getString(MESSAGE));
        }
        var model = J.o2m(object, Department.class);
        model.setCreateId(userId.get());
        model = deptService.model(model);
        if(model == null) {
            return R.error("数据创建失败");
        }
        return R.ok("数据创建成功", model);
    }

    @PutMapping("/dept/{id}")
    @ApiOperation("修改数据")
    @Permission(authorities = "base-dept-update")
    public Object update(@ApiParam("数据id") @PathVariable Long id,
                         @ApiParam("数据对象") @RequestBody DocDepartment object){
        var model = deptService.getById(id);
        if(model == null) {
            return R.error("数据id异常");
        }

        var check = V.checkEmpty(baseVerify(), object);
        if (check.getBoolean(CHECK)) {
            return R.error(check.getString(MESSAGE));
        }

        model = J.o2m(object, Department.class);
        model.setId(id);
        model.setUpdateId(userId.get());

        model = deptService.model(model);
        if(model == null) {
            return R.error("数据修改失败");
        }else {
            return R.ok("数据修改成功", model);
        }
    }

    @DeleteMapping("/dept/{id}")
    @ApiOperation("删除数据")
    @Permission(authorities = "base-dept-delete")
    public Object delete(@ApiParam("数据id") @PathVariable Long id){
        var model = deptService.getById(id);
        if(model == null){
            return R.error("数据id异常");
        }
        if(model.getParentId().longValue() == 0L){
            return R.error("禁止删除顶层部门数据");
        }

        var dqw = new QueryWrapper<Department>();
        dqw.lambda().eq(Department::getParentId, id);
        var depts = deptService.list(dqw);
        if(depts.size() > 0){
            return R.error("该部门下有子部门信息禁止直接删除");
        }

        var qw = new QueryWrapper<UserDepartment>();
        qw.lambda().eq(UserDepartment::getDepartmentId, id);
        var uds = userDeptService.list(qw);
        if(uds.size() > 0){
            return R.error("该部门下有员工信息禁止直接删除");
        }

        if(deptService.removeById(id)) {
            return R.ok("数据删除成功", J.create("id", id));
        }
        return R.error("数据删除失败");
    }

    @GetMapping("/dept-user-query/{key}")
    @ApiOperation("查询用户")
    @Permission(authorities = "base-dept-user-query")
    public Object queryUsersByKey(@ApiParam("查询关键字") @PathVariable String key){
        var qw = new QueryWrapper<User>();
        qw.lambda().or(c ->
                        c.like(User::getLoginName, key).or()
                            .like(User::getTrueName, key).or()
                            .like(User::getNickName, key).or()
                            .like(User::getPhone, key));
        var users = userService.list(qw);
        return R.ok(users);
    }

    @GetMapping("/dept-user")
    @ApiOperation("读取数据")
    @Permission(authorities = "base-dept-user-table")
    public Object tableUser(@ApiParam("部门id") @RequestParam(value = "deptId", required = false, defaultValue = "1") Long deptId,
                            @ApiParam("页码") @RequestParam(value = "page", required = false, defaultValue = "1") int page,
                            @ApiParam("页长") @RequestParam(value = "limit", required = false, defaultValue = "50") int limit){
        var p = new Page<UserDepartment>(page, limit);
        var qw = new QueryWrapper<UserDepartment>();
        qw.lambda().eq(UserDepartment::getDepartmentId, deptId)
                .orderByDesc(UserDepartment::getCreateTime);
        var data = userDeptService.page(p, qw);
        var depts = p2t(data);
        var uds = data.getRecords();

        var list = J.list();
        if(uds.size() > 0) {
            // 处理用户
            var userIds = uds.stream()
                    .map(m -> m.getUserId())
                    .distinct()
                    .collect(Collectors.toList());
            var users = userService.listByIds(userIds);
            if(users.size() > 0){
                uds.stream().forEach(u -> {
                    var user = f2u(users, u.getUserId());
                    if(user != null){
                        list.add(user);
                    }
                });
            }
        }
        depts.put("data", list);
        return depts;
    }

    /**
     * 处理用户信息
     * */
    private JSONObject f2u(List<User> users, Long userId){
        var opt = users.stream()
                        .filter(u -> u.getId().equals(userId))
                        .filter(Objects::nonNull)
                        .findFirst();
        if(opt.isPresent()){
            var model = opt.get();
            var user = J.create("loginName", model.getLoginName())
                    .put("trueName", model.getTrueName())
                    .put("nickName", model.getNickName())
                    .put("avatar", model.getAvatar())
                    .put("phone", model.getPhone())
                    .put("sex", model.getSex())
                    .put("state", model.getState())
                    .put("id", model.getId());
            return user;
        }
        return null;
    }

    @PostMapping("/dept-user")
    @ApiOperation("给部门添加用户")
    @Permission(authorities = "base-dept-add-user")
    public Object addUser(@ApiParam("数据对象") @RequestBody DocUserDept object){
        var check = V.checkEmpty(deptUserVerify(), object);
        if (check.getBoolean(CHECK)) {
            return R.error(check.getString(MESSAGE));
        }
        // 检查是否已经在部门里
        var qw = new QueryWrapper<UserDepartment>();
        qw.lambda()
                .eq(UserDepartment::getDepartmentId, object.getDepartmentId())
                .eq(UserDepartment::getUserId, object.getUserId());
        var ud = userDeptService.getOne(qw);
        if (ud != null){
            return R.error("该用户当前已经在本部门里面");
        }

        var model = J.o2m(object, UserDepartment.class);
        model.setCreateId(userId.get());

        model = userDeptService.model(model);
        if(model == null) {
            return R.error("用户分配失败");
        }
        return R.ok("用户分配成功", model);
    }

    @DeleteMapping("/dept-user/{userId}-{departmentId}")
    @ApiOperation("部门移除用户")
    @Permission(authorities = "base-dept-delete-user")
    public Object deleteUser(@ApiParam("用户id") @PathVariable Long userId,
                             @ApiParam("部门Id") @PathVariable Long departmentId){
        // 检查是否已经在部门里
        var qw = new QueryWrapper<UserDepartment>();
        qw.lambda()
                .eq(UserDepartment::getDepartmentId, departmentId)
                .eq(UserDepartment::getUserId, userId);
        var ud = userDeptService.list(qw);
        if (ud.size() == 0){
            return R.error("数据异常");
        }
        ud.stream().map(x -> x.getId())
                .collect(Collectors.toList())
                .forEach(x -> userDeptService.removeById(x));

        return R.ok("人员移除成功", J.create("id", ud.get(0).getId()));
    }

}
